using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using DanielSig.UnityExtensions;

public enum Player
{
	PlayerOne,
	PlayerTwo
}

public class GameCore : MonoBehaviour
{
	public static int IterationsPerFrame = 1;
	
	public Rect GameTimeSliderRect;
	public TextAnchor GameTimeSliderAnchor;
	public Rect GameTimeRect;
	public TextAnchor GameTimeAnchor;
	public Rect NewGameRect;
	public TextAnchor NewGameAnchor;
	public Rect RestartRect;
	public TextAnchor RestartAnchor;
	
	public GameObject ContinuousSpawner;
	
	public int IterationsStartAt = 1;
	public int MaxAllowedIterations = 40;
	public int MaxTurnsPerGame = 3000;
	
	private bool _startingNewGame = false;
	private static LinkedList<Action> _actions = new LinkedList<Action>();
	private int _turnCount = 0;
	
	void Start()
	{
		IterationsPerFrame = IterationsStartAt;
		StartNewGame();
	}
	[ContextMenu ("New Game")]
	void StartNewGame()
	{
		StartCoroutine(StartGameProcedure());
	}
	private IEnumerator StartGameProcedure()//Ecclesiastes 3:3
	{
		//"There is a time to destroy [the old game]"
		_startingNewGame = true;
		SendMessage("DestroyAllSpawns");//destroy old obstacles and players
		ContinuousSpawner.SendMessage("DestroyAllSpawns");//destroy old health-packs and ammo-packs
		ContinuousSpawner.SendMessage("StartSpawning");//start spawning health-packs and ammo-packs anew
		_actions = new LinkedList<Action>();
		_turnCount = 0;
		
		yield return new WaitForEndOfFrame();//waiting for destruction to finish before creating new stuff
		
		
		//"and a time to build [the new game]"
		SendMessage("SpawnNow");//spawn obstacles, spawn players
		SendMessage("StopSpawning");//don't spawn any more obstacles or players
		_startingNewGame = false;
	}
	
	void OnGUI()
	{
		GUI.Box(GameTimeRect.InScreenPixels(GameTimeAnchor), IterationsPerFrame.ToString());
		
		if(GUI.Button(NewGameRect.InScreenPixels(NewGameAnchor), "New Game"))
			StartNewGame();
		if(GUI.RepeatButton(RestartRect.InScreenPixels(RestartAnchor), "Restart"))
			GameObject.Find("Apprentice2(Clone)").SendMessage("Restart");
		
		float logarithm = Mathf.Log(IterationsPerFrame, 2);
		logarithm = GUI.HorizontalSlider(GameTimeSliderRect.InScreenPixels(GameTimeSliderAnchor), logarithm, 0.5F, Mathf.Log(MaxAllowedIterations, 2));
		IterationsPerFrame = Mathf.RoundToInt(Mathf.Pow(2, logarithm));
	}
	public void OnPlayerDeath(Player deadPlayer)
	{
		if(!_startingNewGame)
		{
			Debug.Log("The winner is " + (deadPlayer == Player.PlayerOne ? Player.PlayerTwo : Player.PlayerOne));
			StartNewGame();
		}
	}
	void FixedUpdate()
	{
		for(int i = 0; i < IterationsPerFrame; i++)
		{
			if(_turnCount++ > MaxTurnsPerGame)
			{
				StartNewGame();
				return;
			}
			LinkedListNode<Action> current = _actions.First;
			while(current != null)
			{
				LinkedListNode<Action> next = current.Next;
				current.Value();
				current = next;
			}
		}
	}
	public static void Register(Action action)
	{
		_actions.AddLast(action);
	}
	public static void Unregister(Action action)
	{
		_actions.Remove(action);
	}
}
